module top(
	input 	wire	rst_n,

	output 	wire 	uart0_tx,
	input	wire	uart0_rx,
	output 	wire 	uart1_tx,
	input	wire	uart1_rx,
	output 	wire 	uart2_tx,
	input	wire	uart2_rx,

	inout	wire    SCL0     ,
    inout	wire    SDA0     ,
	inout	wire    SCL1     ,
    inout	wire    SDA1     ,
	inout	wire    SCL2     ,
    inout	wire    SDA2     ,

    inout	wire    spi0_clk ,
    inout	wire    spi0_cs  ,
    inout	wire    spi0_hold,
    inout	wire    spi0_wp  ,
    inout	wire    spi0_miso,
    inout	wire    spi0_mosi,

	inout	wire    spi1_clk ,
    inout	wire    spi1_cs  ,
    inout	wire    spi1_hold,
    inout	wire    spi1_wp  ,
    inout	wire    spi1_miso,
    inout	wire    spi1_mosi,

	output [31:0] 	sram_test,
	output	[2:0] 	led,
	input	wire 	button
);

/******************************参数***********************************/

/****************************wire类型*********************************/
wire  			clk_cpu;
wire  			rstn_cpu;
wire  [31:0] 	u_m3soc_gpio0_ext_porta_i;
wire  [31:0] 	u_m3soc_gpio0_porta_ddr_o;
wire  [31:0] 	u_m3soc_gpio0_porta_dr_o;

wire  [31:0] 	u_m3soc_sram2_rdat;
wire  [23:0] 	u_m3soc_sram2_addr;
wire  [3:0] 	u_m3soc_sram2_bl;
wire  			u_m3soc_sram2_ce;
wire  			u_m3soc_sram2_clk;
wire  [31:0] 	u_m3soc_sram2_wdat;
wire  			u_m3soc_sram2_wr;
wire [31:0]		gpio_ext_porta;
wire [31:0]		gpio_porta_ddr;
wire [31:0]		gpio_porta_dr;

//SPI
wire              u_m3soc_spi0_clk_in_i     ;
wire              u_m3soc_spi0_cs_n_in_i    ;
wire              u_m3soc_spi0_clk_oe_o     ;
wire              u_m3soc_spi0_clk_out_o    ;
wire              u_m3soc_spi0_cs_n_oe_o    ;
wire              u_m3soc_spi0_cs_n_out_o   ;
wire              u_m3soc_spi0_mosi_in_i    ;
wire              u_m3soc_spi0_mosi_oe_o    ;
wire              u_m3soc_spi0_mosi_out_o   ;
wire              u_m3soc_spi0_miso_in_i    ;
wire              u_m3soc_spi0_miso_oe_o    ;
wire              u_m3soc_spi0_miso_out_o   ;
wire              u_m3soc_spi0_hold_n_in_i  ;
wire              u_m3soc_spi0_hold_n_oe_o  ;
wire              u_m3soc_spi0_hold_n_out_o ;
wire              u_m3soc_spi0_wp_n_in_i    ;
wire              u_m3soc_spi0_wp_n_oe_o    ;
wire              u_m3soc_spi0_wp_n_out_o   ;

wire              u_m3soc_spi1_clk_in_i     ;
wire              u_m3soc_spi1_cs_n_in_i    ;
wire              u_m3soc_spi1_clk_oe_o     ;
wire              u_m3soc_spi1_clk_out_o    ;
wire              u_m3soc_spi1_cs_n_oe_o    ;
wire              u_m3soc_spi1_cs_n_out_o   ;
wire              u_m3soc_spi1_mosi_in_i    ;
wire              u_m3soc_spi1_mosi_oe_o    ;
wire              u_m3soc_spi1_mosi_out_o   ;
wire              u_m3soc_spi1_miso_in_i    ;
wire              u_m3soc_spi1_miso_oe_o    ;
wire              u_m3soc_spi1_miso_out_o   ;
wire              u_m3soc_spi1_hold_n_in_i  ;
wire              u_m3soc_spi1_hold_n_oe_o  ;
wire              u_m3soc_spi1_hold_n_out_o ;
wire              u_m3soc_spi1_wp_n_in_i    ;
wire              u_m3soc_spi1_wp_n_oe_o    ;
wire              u_m3soc_spi1_wp_n_out_o   ;

//IIC0
reg               scl0_r                 ;
reg               sda0_r                 ;
wire              u_m3soc_ic0_clk_in_a   ;
wire              u_m3soc_ic0_clk_oe     ;
wire              u_m3soc_ic0_data_in_a_i;
wire              u_m3soc_ic0_data_oe_o  ;
// IIC1
reg               scl1_r                 ;
reg               sda1_r                 ;
wire              u_m3soc_ic1_clk_in_a   ;
wire              u_m3soc_ic1_clk_oe     ;
wire              u_m3soc_ic1_data_in_a_i;
wire              u_m3soc_ic1_data_oe_o  ;
// IIC2
reg               scl2_r                 ;
reg               sda2_r                 ;
wire              u_m3soc_ic2_clk_in_a   ;
wire              u_m3soc_ic2_clk_oe     ;
wire              u_m3soc_ic2_data_in_a_i;
wire              u_m3soc_ic2_data_oe_o  ;


wire  			clk_osc;
wire  			rstn_cpu;
wire  			locked;
wire   			pclk;
wire  			clk_cpu;

wire  [31:0] 	func;
wire  [31:0] 	wdata;
wire  [31:0] 	sram_rdata;
wire  			clk_ref;

/*****************************reg类型*********************************/

/****************************组合逻辑*********************************/
assign rstn_cpu = locked & rst_n;

assign sram_test = {
	1'b1,
	u_m3soc_sram2_wdat[7:0],
	u_m3soc_sram2_rdat[7:0],
	u_m3soc_sram2_addr[7:0],
	u_m3soc_sram2_bl,
	u_m3soc_sram2_wr,
	u_m3soc_sram2_ce,
	u_m3soc_sram2_clk
};


/******************************例化***********************************/
oscillator_v1 u_osc(
    .clkout(clk_osc)
);

pll_v1 u_pll(
	.clkin0 	(clk_osc),
	.locked 	(locked),
	.clkout0 	(clk_cpu),
	.clkout1    (pclk),
	.clkout2 	(clk_ref)
);

soc_system_v1 u_soc(
    .m3soc_clk_o 				(clk_cpu),
    .m3soc_clken 				(1'b1),
    .m3soc_rstn 				(rstn_cpu),
	.u_m3soc_gpio0_ext_porta_i	(gpio_ext_porta),
    .u_m3soc_gpio0_porta_ddr_o	(gpio_porta_ddr),
    .u_m3soc_gpio0_porta_dr_o	(gpio_porta_dr),

    .u_m3soc_uart0_cts_n_i 		(),
    .u_m3soc_uart0_dcd_n_i 		(),
    .u_m3soc_uart0_dsr_n_i 		(),
    .u_m3soc_uart0_ri_n_i 		(),
    .u_m3soc_uart0_dtr_n_o 		(),
    .u_m3soc_uart0_out1_n_o 	(),
    .u_m3soc_uart0_out2_n_o 	(),
    .u_m3soc_uart0_rts_n_o 		(),
    .u_m3soc_uart0_sin_i 		(uart0_rx),
    .u_m3soc_uart0_sout_o 		(uart0_tx),
    .u_m3soc_uart0_sir_in_i 	(),
    .u_m3soc_uart0_sir_out_n_o  (),
    .u_m3soc_uart0_baudout_n_o  (),

    .u_m3soc_uart1_cts_n_i 		(),
    .u_m3soc_uart1_dcd_n_i 		(),
    .u_m3soc_uart1_dsr_n_i 		(),
    .u_m3soc_uart1_ri_n_i 		(),
    .u_m3soc_uart1_dtr_n_o 		(),
    .u_m3soc_uart1_out1_n_o 	(),
    .u_m3soc_uart1_out2_n_o 	(),
    .u_m3soc_uart1_rts_n_o 		(),
    .u_m3soc_uart1_sin_i 		(uart1_rx),
    .u_m3soc_uart1_sout_o 		(uart1_tx),
    .u_m3soc_uart1_sir_in_i 	(),
    .u_m3soc_uart1_sir_out_n_o  (),
    .u_m3soc_uart1_baudout_n_o  (),

    .u_m3soc_uart2_cts_n_i 		(),
    .u_m3soc_uart2_dcd_n_i 		(),
    .u_m3soc_uart2_dsr_n_i 		(),
    .u_m3soc_uart2_ri_n_i 		(),
    .u_m3soc_uart2_dtr_n_o 		(),
    .u_m3soc_uart2_out1_n_o 	(),
    .u_m3soc_uart2_out2_n_o 	(),
    .u_m3soc_uart2_rts_n_o 		(),
    .u_m3soc_uart2_sin_i 		(uart2_rx),
    .u_m3soc_uart2_sout_o 		(uart2_tx),
    .u_m3soc_uart2_sir_in_i 	(),
    .u_m3soc_uart2_sir_out_n_o  (),
    .u_m3soc_uart2_baudout_n_o  (),

    .u_m3soc_spi0_clk_in_i     (u_m3soc_spi0_clk_in_i      ),
    .u_m3soc_spi0_cs_n_in_i    (u_m3soc_spi0_cs_n_in_i     ),
    .u_m3soc_spi0_clk_oe_o     (u_m3soc_spi0_clk_oe_o      ),
    .u_m3soc_spi0_clk_out_o    (u_m3soc_spi0_clk_out_o     ),
    .u_m3soc_spi0_cs_n_oe_o    (u_m3soc_spi0_cs_n_oe_o     ),
    .u_m3soc_spi0_cs_n_out_o   (u_m3soc_spi0_cs_n_out_o    ),
    .u_m3soc_spi0_mosi_in_i    (u_m3soc_spi0_mosi_in_i     ),
    .u_m3soc_spi0_mosi_oe_o    (u_m3soc_spi0_mosi_oe_o     ),
    .u_m3soc_spi0_mosi_out_o   (u_m3soc_spi0_mosi_out_o    ),
    .u_m3soc_spi0_miso_in_i    (u_m3soc_spi0_miso_in_i     ),
    .u_m3soc_spi0_miso_oe_o    (u_m3soc_spi0_miso_oe_o     ),
    .u_m3soc_spi0_miso_out_o   (u_m3soc_spi0_miso_out_o    ),
    .u_m3soc_spi0_hold_n_in_i  (u_m3soc_spi0_hold_n_in_i   ),
    .u_m3soc_spi0_hold_n_oe_o  (u_m3soc_spi0_hold_n_oe_o   ),
    .u_m3soc_spi0_hold_n_out_o (u_m3soc_spi0_hold_n_out_o  ),
    .u_m3soc_spi0_wp_n_in_i    (u_m3soc_spi0_wp_n_in_i     ),
    .u_m3soc_spi0_wp_n_oe_o    (u_m3soc_spi0_wp_n_oe_o     ),
    .u_m3soc_spi0_wp_n_out_o   (u_m3soc_spi0_wp_n_out_o    ),

    .u_m3soc_spi1_clk_in_i     (u_m3soc_spi1_clk_in_i      ),
    .u_m3soc_spi1_cs_n_in_i    (u_m3soc_spi1_cs_n_in_i     ),
    .u_m3soc_spi1_clk_oe_o     (u_m3soc_spi1_clk_oe_o      ),
    .u_m3soc_spi1_clk_out_o    (u_m3soc_spi1_clk_out_o     ),
    .u_m3soc_spi1_cs_n_oe_o    (u_m3soc_spi1_cs_n_oe_o     ),
    .u_m3soc_spi1_cs_n_out_o   (u_m3soc_spi1_cs_n_out_o    ),
    .u_m3soc_spi1_mosi_in_i    (u_m3soc_spi1_mosi_in_i     ),
    .u_m3soc_spi1_mosi_oe_o    (u_m3soc_spi1_mosi_oe_o     ),
    .u_m3soc_spi1_mosi_out_o   (u_m3soc_spi1_mosi_out_o    ),
    .u_m3soc_spi1_miso_in_i    (u_m3soc_spi1_miso_in_i     ),
    .u_m3soc_spi1_miso_oe_o    (u_m3soc_spi1_miso_oe_o     ),
    .u_m3soc_spi1_miso_out_o   (u_m3soc_spi1_miso_out_o    ),
    .u_m3soc_spi1_hold_n_in_i  (u_m3soc_spi1_hold_n_in_i   ),
    .u_m3soc_spi1_hold_n_oe_o  (u_m3soc_spi1_hold_n_oe_o   ),
    .u_m3soc_spi1_hold_n_out_o (u_m3soc_spi1_hold_n_out_o  ),
    .u_m3soc_spi1_wp_n_in_i    (u_m3soc_spi1_wp_n_in_i     ),
    .u_m3soc_spi1_wp_n_oe_o    (u_m3soc_spi1_wp_n_oe_o     ),
    .u_m3soc_spi1_wp_n_out_o   (u_m3soc_spi1_wp_n_out_o    ),

    .u_m3soc_ic0_clk_in_a      (u_m3soc_ic0_clk_in_a       ),
    .u_m3soc_ic0_clk_oe        (u_m3soc_ic0_clk_oe         ),
    .u_m3soc_ic0_data_in_a_i   (u_m3soc_ic0_data_in_a_i    ),
    .u_m3soc_ic0_data_oe_o     (u_m3soc_ic0_data_oe_o      ),

    .u_m3soc_ic1_clk_in_a      (u_m3soc_ic1_clk_in_a       ),
    .u_m3soc_ic1_clk_oe        (u_m3soc_ic1_clk_oe         ),
    .u_m3soc_ic1_data_in_a_i   (u_m3soc_ic1_data_in_a_i    ),
    .u_m3soc_ic1_data_oe_o     (u_m3soc_ic1_data_oe_o      ),

    .u_m3soc_ic2_clk_in_a      (u_m3soc_ic2_clk_in_a       ),
    .u_m3soc_ic2_clk_oe        (u_m3soc_ic2_clk_oe         ),
    .u_m3soc_ic2_data_in_a_i   (u_m3soc_ic2_data_in_a_i    ),
    .u_m3soc_ic2_data_oe_o     (u_m3soc_ic2_data_oe_o      ),

    .u_m3soc_sram2_rdat 		(u_m3soc_sram2_rdat 		),
    .u_m3soc_sram2_addr 		(u_m3soc_sram2_addr 		),
    .u_m3soc_sram2_bl 			(u_m3soc_sram2_bl 			),
    .u_m3soc_sram2_ce 			(u_m3soc_sram2_ce 			),
    .u_m3soc_sram2_clk 			(u_m3soc_sram2_clk 			),
    .u_m3soc_sram2_wdat 		(u_m3soc_sram2_wdat 		),
    .u_m3soc_sram2_wr 			(u_m3soc_sram2_wr 			)
);

//gpio
assign led = gpio_porta_dr[2:0] & gpio_porta_ddr[2:0];
assign gpio_ext_porta[3] = button;

//spi
assign u_m3soc_spi0_clk_in_i    =   spi0_clk  ;
assign u_m3soc_spi0_cs_n_in_i   =   spi0_cs   ;
assign u_m3soc_spi0_hold_n_in_i =   spi0_hold ;
assign u_m3soc_spi0_miso_in_i   =   spi0_miso ;
assign u_m3soc_spi0_mosi_in_i   =   spi0_mosi ;
assign u_m3soc_spi0_wp_n_in_i   =   spi0_wp   ;

assign spi0_clk  = u_m3soc_spi0_clk_oe_o    ? u_m3soc_spi0_clk_out_o   : 1'bz ;
assign spi0_cs   = u_m3soc_spi0_cs_n_oe_o   ? u_m3soc_spi0_cs_n_out_o  : 1'bz ; //gpio_porta_dr[5];
assign spi0_hold = u_m3soc_spi0_hold_n_oe_o ? u_m3soc_spi0_hold_n_out_o: 1'bz ;
assign spi0_miso = u_m3soc_spi0_miso_oe_o   ? u_m3soc_spi0_miso_out_o  : 1'bz ;
assign spi0_mosi = u_m3soc_spi0_mosi_oe_o   ? u_m3soc_spi0_mosi_out_o  : 1'bz ;
assign spi0_wp   = u_m3soc_spi0_wp_n_oe_o   ? u_m3soc_spi0_wp_n_out_o  : 1'bz ;

assign u_m3soc_spi1_clk_in_i    =   spi1_clk  ;
assign u_m3soc_spi1_cs_n_in_i   =   spi1_cs   ;
assign u_m3soc_spi1_hold_n_in_i =   spi1_hold ;
assign u_m3soc_spi1_miso_in_i   =   spi1_miso ;
assign u_m3soc_spi1_mosi_in_i   =   spi1_mosi ;
assign u_m3soc_spi1_wp_n_in_i   =   spi1_wp   ;

assign spi1_clk  = u_m3soc_spi1_clk_oe_o    ? u_m3soc_spi1_clk_out_o   : 1'bz ;
assign spi1_cs   = u_m3soc_spi1_cs_n_oe_o   ? u_m3soc_spi1_cs_n_out_o  : 1'bz ;
assign spi1_hold = u_m3soc_spi1_hold_n_oe_o ? u_m3soc_spi1_hold_n_out_o: 1'bz ;
assign spi1_miso = u_m3soc_spi1_miso_oe_o   ? u_m3soc_spi1_miso_out_o  : 1'bz ;
assign spi1_mosi = u_m3soc_spi1_mosi_oe_o   ? u_m3soc_spi1_mosi_out_o  : 1'bz ;
assign spi1_wp   = u_m3soc_spi1_wp_n_oe_o   ? u_m3soc_spi1_wp_n_out_o  : 1'bz ;

//IIC 0
always @(posedge clk_cpu) begin
    scl0_r <= 1'b0;
    sda0_r <= 1'b0;
end
assign SCL0 = u_m3soc_ic0_clk_oe    ? scl0_r : 1'bz;
assign SDA0 = u_m3soc_ic0_data_oe_o ? sda0_r : 1'bz;
assign u_m3soc_ic0_clk_in_a    = SCL0;
assign u_m3soc_ic0_data_in_a_i = SDA0;

//IIC1
always @(posedge clk_cpu) begin
    scl1_r <= 1'b0;
    sda1_r <= 1'b0;
end
assign SCL1 = u_m3soc_ic1_clk_oe    ? scl1_r : 1'bz;
assign SDA1 = u_m3soc_ic1_data_oe_o ? sda1_r : 1'bz;
assign u_m3soc_ic1_clk_in_a    = SCL1;
assign u_m3soc_ic1_data_in_a_i = SDA1;

//IIC2
always @(posedge clk_cpu) begin
    scl2_r <= 1'b0;
    sda2_r <= 1'b0;
end
assign SCL2 = u_m3soc_ic2_clk_oe    ? scl2_r : 1'bz;
assign SDA2 = u_m3soc_ic2_data_oe_o ? sda2_r : 1'bz;
assign u_m3soc_ic2_clk_in_a    = SCL2;
assign u_m3soc_ic2_data_in_a_i = SDA2;

emb_v1 u_emb_v1(
	.clk	(clk_cpu),
	.ce		(~u_m3soc_sram2_ce),
	.we		(~u_m3soc_sram2_wr),
	.rstn	(rst_n),
	.a		(u_m3soc_sram2_addr[16:2]),
	.d		(u_m3soc_sram2_wdat),
	.q		(u_m3soc_sram2_rdat)
	);

endmodule
